import { Injectable, Logger, OnModuleInit } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { ConfigService } from "@nestjs/config";
import { Repository } from "typeorm";
import { TimeUnit } from "st-common-core";
import { EnvNameEnum } from "../common/env";
import { getWithParse, set } from "../common/redis";
import { RoleService } from "../role";
import { UserRoleService } from "../user-role";
import { User } from "./entities/User";
import { encryptUserPassword, genUserAccount, genUserSalt } from "./utils/user.util";
import { RootUserInfoConst } from "./consts/root-user-info.const";

/**
 * Redis 缓存键前缀
 */
const REDIS_KEY_PREFIX = {
  USER_LIST: "user:list:",
  USER_TOTAL: "user:total:",
};

/**
 * 生成用户列表缓存的key
 */
const generateUserListCacheKey = (options: any) => {
  const {
    page = 1,
    pageSize = 10,
    username,
    nickname,
    email,
    account,
    disabled,
    startTime,
    endTime,
    orderBy = "createTime",
    order = "DESC"
  } = options;

  return `${REDIS_KEY_PREFIX.USER_LIST}${JSON.stringify({
    page,
    pageSize,
    username,
    nickname,
    email,
    account,
    disabled,
    startTime,
    endTime,
    orderBy,
    order
  })}`;
};

/**
 * 生成用户总数缓存的key
 */
const generateUserTotalCacheKey = (options: any) => {
  const {
    username,
    nickname,
    email,
    account,
    disabled,
    startTime,
    endTime
  } = options;

  return `${REDIS_KEY_PREFIX.USER_TOTAL}${JSON.stringify({
    username,
    nickname,
    email,
    account,
    disabled,
    startTime,
    endTime
  })}`;
};

/**
 * 用户服务
 */
@Injectable()
export class UserService implements OnModuleInit {

  private readonly logger = new Logger(UserService.name);

  constructor(
    @InjectRepository(User)
    private readonly userRepository: Repository<User>,
    private readonly roleService: RoleService,
    private readonly userRoleService: UserRoleService,
    private readonly configService: ConfigService
  ) {
  }

  async onModuleInit() {
    await this.createRootUser();
  }

  /**
   * 创建超级管理员用户<br/>
   * 如果数据库中不存在超级管理员用户，则创建超级管理员用户并给其添加超级管理员角色
   *
   * @returns {Promise<void>}
   */
  async createRootUser() {
    // 判断是否需要创建然后获取超级管理员角色
    const rootRole = await this.roleService.createRoot();
    // 获取超级管理员角色的角色用户关系
    const rootRoleUser = await this.userRoleService.findByRoleId(rootRole.id);
    // 超级管理员用户不存在
    if (rootRoleUser.length === 0) {
      this.logger.log("超级管理员用户不存在，开始创建...");
      // 生成超级管理员用户账号
      const rootUserAccount = genUserAccount();
      // 生成密码加密盐
      const rootUserSalt = genUserSalt();
      // 密码加密预处理
      let rootUserPassword = this.configService.get<string>(EnvNameEnum.ROOT_USER_PASSWORD_DEFAULT) ?? RootUserInfoConst.PASSWORD_DEFAULT;
      rootUserPassword = encryptUserPassword(rootUserPassword, rootUserSalt);
      let rootUser = {
        account: rootUserAccount,
        username: this.configService.get<string>(EnvNameEnum.ROOT_USER_USERNAME) ?? RootUserInfoConst.USERNAME,
        nickname: this.configService.get<string>(EnvNameEnum.ROOT_USER_NICKNAME_DEFAULT) ?? RootUserInfoConst.NICKNAME_DEFAULT,
        password: rootUserPassword,
        remark: this.configService.get<string>(EnvNameEnum.ROOT_USER_REMARK_DEFAULT) ?? RootUserInfoConst.REMARK_DEFAULT,
        salt: rootUserSalt
      } as User;
      rootUser = await this.userRepository.save(rootUser);
      // 给超级管理员用户添加超级管理员角色
      await this.userRoleService.save(rootUser.id, rootRole.id);
      this.logger.log("超级管理员用户创建成功！");
    }
  }

  /**
   * 根据用户名或账号查询用户信息
   *
   * @param {string} usernameOrAccount 用户名或账号
   * @returns {Promise<User>} 用户信息
   */
  async findByUsernameOrAccount(usernameOrAccount: string) {
    return await this.userRepository
      .createQueryBuilder()
      .where("username = :username", { username: usernameOrAccount })
      .orWhere("account = :account", { account: usernameOrAccount })
      .getOne();
  }

  // async findUsers() {
  //   return await this.userRepository
  //     .find();
  // }
  //
  // /**
  //  * 创建新用户
  //  * @param user 用户信息
  //  */
  // async create(user: Partial<User>): Promise<User> {
  //   // 生成账号
  //   user.account = genUserAccount();
  //   // 生成密码盐
  //   user.salt = genUserSalt();
  //   // 加密密码
  //   user.password = encryptUserPassword(user.password, user.salt);
  //
  //   const result = await this.userRepository.save(user);
  //   await this.clearUserListCache();
  //   return result;
  // }
  //
  // /**
  //  * 更新用户信息
  //  * @param id 用户ID
  //  * @param user 更新的用户信息
  //  */
  // async update(id: number, user: Partial<User>): Promise<boolean> {
  //   // 如果要更新密码，需要重新加密
  //   if (user.password) {
  //     user.salt = genUserSalt();
  //     user.password = encryptUserPassword(user.password, user.salt);
  //   }
  //
  //   const result = await this.userRepository.update(id, user);
  //   await this.clearUserListCache();
  //   return result.affected > 0;
  // }
  //
  // /**
  //  * 删除用户
  //  * @param id 用户ID
  //  */
  // async delete(id: number): Promise<boolean> {
  //   const result = await this.userRepository.softDelete(id);
  //   await this.clearUserListCache();
  //   return result.affected > 0;
  // }
  //
  // /**
  //  * 查询用户列表
  //  * @param options 查询选项
  //  * @param options.page 页码
  //  * @param options.pageSize 每页数量
  //  * @param options.username 用户名（模糊查询）
  //  * @param options.nickname 昵称（模糊查询）
  //  * @param options.email 邮箱（模糊查询）
  //  * @param options.account 账号（模糊查询）
  //  * @param options.disabled 是否禁用
  //  * @param options.startTime 创建开始时间
  //  * @param options.endTime 创建结束时间
  //  * @param options.orderBy 排序字段
  //  * @param options.order 排序方式
  //  */
  // async findList(options: {
  //   page?: number;
  //   pageSize?: number;
  //   username?: string;
  //   nickname?: string;
  //   email?: string;
  //   account?: string;
  //   disabled?: boolean;
  //   startTime?: Date;
  //   endTime?: Date;
  //   orderBy?: string;
  //   order?: "ASC" | "DESC";
  // } = {}): Promise<[User[], number]> {
  //   // 生成缓存key
  //   const listCacheKey = generateUserListCacheKey(options);
  //   const totalCacheKey = generateUserTotalCacheKey(options);
  //
  //   // 尝试从缓存获取数据
  //   const cachedList = await getWithParse<User[]>(listCacheKey);
  //   const cachedTotal = await getWithParse<number>(totalCacheKey);
  //
  //   // 如果缓存中有数据，直接返回
  //   if (cachedList && cachedTotal !== null) {
  //     return [cachedList, cachedTotal];
  //   }
  //
  //   // 如果缓存中没有数据，从数据库查询
  //   const {
  //     page = 1,
  //     pageSize = 10,
  //     username,
  //     nickname,
  //     email,
  //     account,
  //     disabled,
  //     startTime,
  //     endTime,
  //     orderBy = "createTime",
  //     order = "DESC"
  //   } = options;
  //
  //   // 创建查询构建器
  //   const queryBuilder = this.userRepository.createQueryBuilder("user");
  //
  //   // 添加查询条件
  //   if (username) {
  //     queryBuilder.andWhere("user.username LIKE :username", { username: `%${username}%` });
  //   }
  //   if (nickname) {
  //     queryBuilder.andWhere("user.nickname LIKE :nickname", { nickname: `%${nickname}%` });
  //   }
  //   if (email) {
  //     queryBuilder.andWhere("user.email LIKE :email", { email: `%${email}%` });
  //   }
  //   if (account) {
  //     queryBuilder.andWhere("user.account LIKE :account", { account: `%${account}%` });
  //   }
  //   if (disabled !== undefined) {
  //     queryBuilder.andWhere("user.disabled = :disabled", { disabled });
  //   }
  //   if (startTime) {
  //     queryBuilder.andWhere("user.createTime >= :startTime", { startTime });
  //   }
  //   if (endTime) {
  //     queryBuilder.andWhere("user.createTime <= :endTime", { endTime });
  //   }
  //
  //   // 添加排序
  //   queryBuilder.orderBy(`user.${orderBy}`, order);
  //
  //   // 添加分页
  //   queryBuilder
  //     .skip((page - 1) * pageSize)
  //     .take(pageSize);
  //
  //   // 执行查询
  //   const [list, total] = await queryBuilder.getManyAndCount();
  //
  //   // 将数据存入缓存
  //   await set({
  //     key: listCacheKey,
  //     value: list,
  //     expire: 300, // 缓存5分钟
  //     unit: TimeUnit.second
  //   });
  //
  //   await set({
  //     key: totalCacheKey,
  //     value: total,
  //     expire: 300, // 缓存5分钟
  //     unit: TimeUnit.second
  //   });
  //
  //   return [list, total];
  // }
  //
  // /**
  //  * 清除用户列表缓存
  //  */
  // private async clearUserListCache(): Promise<void> {
  //   // 删除所有用户列表相关的缓存
  //   await delByPattern(`${REDIS_KEY_PREFIX.USER_LIST}*`);
  //   // 删除所有用户总数相关的缓存
  //   await delByPattern(`${REDIS_KEY_PREFIX.USER_TOTAL}*`);
  // }
  //
  // /**
  //  * 根据ID查询用户（包含角色信息）
  //  * @param id 用户ID
  //  */
  // async findById(id: number): Promise<User & { roles?: any[] }> {
  //   // 查询用户基本信息
  //   const user = await this.userRepository.findOne({
  //     where: { id }
  //   });
  //
  //   if (!user) {
  //     return null;
  //   }
  //
  //   // 查询用户角色关系
  //   const userRoles = await this.userRoleService.findByUserId(id);
  //   if (userRoles && userRoles.length > 0) {
  //     // 查询角色详细信息
  //     const roleIds = userRoles.map(ur => ur.roleId);
  //     const roles = await this.roleService.findByIds(roleIds);
  //     return { ...user, roles };
  //   }
  //
  //   return user;
  // }
}
